package com.livrexpress.livrexpressandroid.work.utility;

import java.io.IOException;
import java.io.InputStream;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import com.livrexpress.livrexpressandroid.localdomain.Delivery;
import com.livrexpress.livrexpressandroid.localdomain.LivreApplication;
import com.livrexpress.livrexpressandroid.localdomain.Package;
import com.livrexpress.livrexpressandroid.localdomain.Person;
import com.livrexpress.livrexpressandroid.localdomain.Tour;

import android.database.Cursor;
import android.util.Xml;

public class LivrexpressXmlParser {
	/**
	 * Parses and saves in local database a XML file representing a delivery tour.
	 * @param in XML as InputStream
	 * @return The generated Tour object.
	 * @throws XmlPullParserException
	 * @throws IOException
	 */
	public Tour parse(InputStream in) throws XmlPullParserException, IOException{
		
		try{
			XmlPullParser parser = Xml.newPullParser();
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
            parser.setInput(in, null);
            parser.nextTag();
            return readXml(parser);
		} catch(Exception e) {
			System.out.println(e.getMessage());
			e.printStackTrace();
			return null;
		} finally {
			in.close();
		}
	}
	
	private Tour readXml(XmlPullParser parser) throws XmlPullParserException, IOException {
	    Tour t = null;
	    //The first tag of the file has to be "tournee"
	    parser.require(XmlPullParser.START_TAG, null, "tournee");
	    while (parser.next() != XmlPullParser.END_TAG) {
	        if (parser.getEventType() != XmlPullParser.START_TAG) {
	            continue;
	        }
	        String name = parser.getName();

            if (name.equals("livreur")) {
                t = readLivreur(parser);
            } else if (name.equals("date_tournee")) {
            	parser.require(XmlPullParser.START_TAG, null, "date_tournee");
				t.setDateTour(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "date_tournee");
				t.insert();
            } else if (name.equals("livraison")) {
                Delivery d = readLivraison(parser);
                d.setIdTour(t.getIdTour());
                d.insert();
            }

	    }  
	    return t;
	}
	
	private Tour readLivreur(XmlPullParser parser) throws IOException, XmlPullParserException {
		parser.require(XmlPullParser.START_TAG, null, "livreur");
		Tour t = new Tour();
		
		while (parser.next() != XmlPullParser.END_TAG) {
			if (parser.getEventType() != XmlPullParser.START_TAG) {
	            continue;
	        }
			String name = parser.getName();
			
			if (name.equals("id")) {
				parser.require(XmlPullParser.START_TAG, null, "id");
				t.setIdLivreur(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "id");
            } else if (name.equals("nom")) {
            	parser.require(XmlPullParser.START_TAG, null, "nom");
				t.setNomLivreur(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "nom");
            }
		}
	    parser.require(XmlPullParser.END_TAG, null, "livreur");
		return t;
	}
	
	private Delivery readLivraison(XmlPullParser parser) throws IOException, XmlPullParserException {
		parser.require(XmlPullParser.START_TAG, null, "livraison");
		Delivery d = new Delivery();
		Person sender = new Person();
		Person recipient = new Person();
		
		
		while (parser.next() != XmlPullParser.END_TAG) {
			if (parser.getEventType() != XmlPullParser.START_TAG) {
	            continue;
	        }
			String name = parser.getName();
			
			if (name.equals("id")) {
				parser.require(XmlPullParser.START_TAG, null, "id");
				d.setIdDelivery(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "id");
            } else if (name.equals("expediteur")) {
            	parser.require(XmlPullParser.START_TAG, null, "expediteur");
            	sender = readPerson(parser);
            	parser.require(XmlPullParser.END_TAG, null, "expediteur");
            	sender.setType(Person.SENDER);
            	sender.insert();
            	d.setIdSender(sender.getIdPerson());
            } else if (name.equals("colis")) {
            	parser.require(XmlPullParser.START_TAG, null, "colis");
            	//Package processing
            	while (parser.next() != XmlPullParser.END_TAG) {
        			if (parser.getEventType() != XmlPullParser.START_TAG) {
        	            continue;
        	        }
        			name = parser.getName();
        			
        			if (name.equals("paquet")) {
        				Package p = readPaquet(parser);
        				p.setIdDelivery(d.getIdDelivery());
        				p.insert();
        			} else if (name.equals("nombre")) {
        				parser.require(XmlPullParser.START_TAG, null, "nombre");
        				readText(parser);
        				parser.require(XmlPullParser.END_TAG, null, "nombre");
        			}
            	}
            	parser.require(XmlPullParser.END_TAG, null, "colis");
            } else if (name.equals("destinataire")) {
            	parser.require(XmlPullParser.START_TAG, null, "destinataire");
            	recipient = readPerson(parser);
            	parser.require(XmlPullParser.END_TAG, null, "destinataire");
            	recipient.setType(Person.RECIPIENT);
            	recipient.insert();
            	d.setIdReceiver(recipient.getIdPerson());
            }
		}
		
		parser.require(XmlPullParser.END_TAG, null, "livraison");
		return d;
	}
	
	private Person readPerson(XmlPullParser parser) throws IOException, XmlPullParserException {
		Person p = new Person();
		
		while (parser.next() != XmlPullParser.END_TAG) {
			if (parser.getEventType() != XmlPullParser.START_TAG) {
	            continue;
	        }
			
			String name = parser.getName();
			if (name.equals("nom")) {
				parser.require(XmlPullParser.START_TAG, null, "nom");
				p.setName(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "nom");
			} else if (name.equals("rue")) {
				parser.require(XmlPullParser.START_TAG, null, "rue");
				p.setStreet(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "rue");
			} else if (name.equals("cp")) {
				parser.require(XmlPullParser.START_TAG, null, "cp");
				p.setZipCode(Integer.parseInt(readText(parser)));
				parser.require(XmlPullParser.END_TAG, null, "cp");
			} else if (name.equals("ville")) {
				parser.require(XmlPullParser.START_TAG, null, "ville");
				p.setCity(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "ville");
			} else if (name.equals("complement_adresse")) {
				parser.require(XmlPullParser.START_TAG, null, "complement_adresse");
				p.setAdditionalAddress(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "complement_adresse");
			} else if (name.equals("telephone")) {
				parser.require(XmlPullParser.START_TAG, null, "telephone");
				p.setTel(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "telephone");
			} else if (name.equals("portable")) {
				parser.require(XmlPullParser.START_TAG, null, "portable");
				p.setMobile(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "portable");
			}
			
		}
		
		return p;
	}
	
	private Package readPaquet(XmlPullParser parser) throws IOException, XmlPullParserException {
		parser.require(XmlPullParser.START_TAG, null, "paquet");
		Package p = new Package();
		
		while (parser.next() != XmlPullParser.END_TAG) {
			if (parser.getEventType() != XmlPullParser.START_TAG) {
	            continue;
	        }
			
			String name = parser.getName();
			if (name.equals("code_barre")) {
				parser.require(XmlPullParser.START_TAG, null, "code_barre");
				p.setIdCodeBarre(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "code_barre");
			} else if (name.equals("taille")) {
				parser.require(XmlPullParser.START_TAG, null, "taille");
				p.setSize(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "taille");
			} else if (name.equals("poids")) {
				parser.require(XmlPullParser.START_TAG, null, "poids");
				p.setWeight(readText(parser));
				parser.require(XmlPullParser.END_TAG, null, "poids");
			}
		}
		
		parser.require(XmlPullParser.END_TAG, null, "paquet");
		return p;
	}
	
	// Extract the text value of a tag
	private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
	    String result = "";
	    if (parser.next() == XmlPullParser.TEXT) {
	        result = parser.getText();
	        parser.nextTag();
	    }
	    return result;
	}

}
